package club.jdiy.admin.freemarker;

import club.jdiy.admin.freemarker.func.*;
import freemarker.cache.ClassTemplateLoader;
import freemarker.cache.MultiTemplateLoader;
import freemarker.cache.TemplateLoader;
import freemarker.template.*;
import no.api.freemarker.java8.Java8ObjectWrapper;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.ui.freemarker.SpringTemplateLoader;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import org.springframework.web.servlet.view.freemarker.FreeMarkerView;
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Locale;
import java.util.Map;

@SpringBootConfiguration
public class FreemarkerConfig {
    //仅影响LocalDateTime,LocalDate,LocalTime三种字段类型在ftl中的格式化方法
    //注意：java.util.Date不受影响
    // ** 为true时:   vo.dtAdd.format('yyyy-MM-dd HH:mm:ss')
    // ** 为false时:  统一使用java.util.Date一样的格式化方法,即：　?datetime, ?date,  ?string('yyyy-MM-dd HH:mm:ss')
    private static final boolean useJava8LocalDateTimeFormatter = false;

    @PostConstruct
    public void init() {
        this.setObjectWrapper();
        configuration.setNumberFormat("0.##");
        configuration.setDateFormat("yyyy-MM-dd");
        configuration.setTimeFormat("HH:mm:ss");
        configuration.setDateTimeFormat("yyyy-MM-dd HH:mm:ss");
        configuration.setLocale(Locale.CHINA);
        configuration.setOutputEncoding("utf-8");
        configuration.setDefaultEncoding("utf-8");
        configuration.setClassicCompatible(true);
        configuration.setTagSyntax(Configuration.AUTO_DETECT_TAG_SYNTAX);
        configuration.setTemplateUpdateDelayMilliseconds(3000);
        //自定义函数:
        configuration.setSharedVariable("cut", cutText);
        configuration.setSharedVariable("grant", grant);
        configuration.setSharedVariable("hasRole", hasRole);
        configuration.setSharedVariable("to_date", timestampToDate);
        configuration.setSharedVariable("getUserInfo", getUserInfo);
        configuration.setSharedVariable("getDictInfo", getDictInfo);
        configurer.setDefaultEncoding("UTF-8");


        //       configurer.setTemplateLoaderPaths("classpath:/");
        TemplateLoader classTemplateLoader = new ClassTemplateLoader(this.getClass(), ".");
        MultiTemplateLoader mt = new MultiTemplateLoader(new TemplateLoader[]{
                classTemplateLoader,
                new SpringTemplateLoader(new DefaultResourceLoader(), "classpath:/")
        });
        configuration.setTemplateLoader(mt);


        resolver.setCache(true);
        resolver.setContentType("text/html;charset=utf-8");
        resolver.setRequestContextAttribute("request");
        resolver.setPrefix("templates/");
        resolver.setSuffix("");
        resolver.setViewNames("*.ftl");


        //增加视图:
        resolver.setViewClass(MyFreemarkerView.class);
        //添加自定义解析器
        //Map<String,Object> map = resolver.getAttributesMap();
        //          map.put("grant", checkRole);//可定义freemarker模板中的方法，见：https://blog.csdn.net/shi0299/article/details/74332593
    }

    private void setObjectWrapper() {
        if (useJava8LocalDateTimeFormatter) {
            configuration.setObjectWrapper(new Java8ObjectWrapper(Configuration.VERSION_2_3_31));
        } else {
            configuration.setObjectWrapper(new DefaultObjectWrapper(Configuration.VERSION_2_3_31) {
                @Override
                public TemplateModel wrap(Object object) throws TemplateModelException {

                    if (object instanceof LocalDate) {
                        return new SimpleDate(Date.valueOf((LocalDate) object));
                    }
                    if (object instanceof LocalTime) {
                        return new SimpleDate(Time.valueOf((LocalTime) object));
                    }
                    if (object instanceof LocalDateTime) {
                        return new SimpleDate(Timestamp.valueOf((LocalDateTime) object));
                    }
                    return super.wrap(object);
                }
            });
        }
    }

    //自定义视图：
    final static class MyFreemarkerView extends FreeMarkerView {
        @Override
        protected void exposeHelpers(Map<String, Object> model, HttpServletRequest request) throws Exception {
            //往model中添加变量
            //model.put("ACCOUNT_TYPE", SysVariables.ACCOUNT_TYPE);
            super.exposeHelpers(model, request);
        }
    }

    @Resource
    private freemarker.template.Configuration configuration;
    @Resource
    FreeMarkerConfigurer configurer;
    @Resource
    private FreeMarkerViewResolver resolver;

    @Resource
    private Grant grant;
    @Resource
    private HasRole hasRole;
    @Resource
    private CutText cutText;
    @Resource
    private TimestampToDate timestampToDate;
    @Resource
    private GetUserInfo getUserInfo;
    @Resource
    private GetDictInfo getDictInfo;
}
